"""
角色控制器
处理角色相关的HTTP请求
"""
from typing import List, Optional
from fastapi import APIRouter, Depends, Query, Path, status
from fastapi.responses import JSONResponse

from pkg.common.utils.response.response import ApiResponse
from pkg.common.constants.response import ResponseCode, ResponseMessage
from apps.auth.schemas.role_schema import (
    RoleCreate, RoleUpdate, RoleWholeUpdate, RoleResponse, 
    RoleListResponse, RoleWithPermissionsResponse
)
from apps.auth.services.role_service import RoleService
from apps.auth.models.role import Role
from apps.auth.models.permission import Permission


# 创建路由器实例
router = APIRouter(prefix="/roles", tags=["角色管理"])


@router.post("", summary="创建角色")
async def create_role(role_data: RoleCreate):
    """
    创建一个新角色
    
    Args:
        role_data: 角色创建数据
        
    Returns:
        包含新创建角色信息的响应
    """
    role = await RoleService.create_role(role_data.model_dump())
    return ApiResponse.success(
        data=RoleResponse.model_validate(role),
        msg="角色创建成功"
    )


@router.get("", summary="获取角色列表")
async def list_roles(
    page: int = Query(1, ge=1, description="页码"),
    page_size: int = Query(10, ge=1, le=50, description="每页项数"),
    search: Optional[str] = Query(None, description="搜索关键词")
):
    """
    获取角色列表，支持分页和搜索
    
    Args:
        page: 页码
        page_size: 每页大小
        search: 搜索关键词
        
    Returns:
        包含角色列表的响应
    """
    roles, total = await RoleService.list_roles(page, page_size, search)
    
    # 计算总页数
    pages = (total + page_size - 1) // page_size if total > 0 else 1
    
    # 构造响应
    response_data = {
        "items": [RoleResponse.model_validate(role) for role in roles],
        "total": total,
        "page": page,
        "page_size": page_size,
        "pages": pages
    }
    
    return ApiResponse.success(data=response_data)


@router.get("/{role_id}", summary="获取角色详情")
async def get_role(
    role_id: int = Path(..., ge=1, description="角色ID")
):
    """
    通过ID获取角色详情
    
    Args:
        role_id: 角色ID
        
    Returns:
        包含角色信息的响应
    """
    role = await RoleService.get_role_by_id(role_id)
    return ApiResponse.success(
        data=RoleResponse.model_validate(role)
    )


@router.put("/{role_id}", summary="更新角色信息")
async def update_role(
    update_data: RoleUpdate,
    role_id: int = Path(..., ge=1, description="角色ID")
):
    """
    更新角色信息(部分更新)
    
    Args:
        update_data: 更新数据
        role_id: 角色ID
        
    Returns:
        包含更新后角色信息的响应
    """
    # 过滤掉None值字段，只更新提供了值的字段
    update_dict = {k: v for k, v in update_data.model_dump().items() if v is not None}
    
    if not update_dict:
        return ApiResponse.success(
            msg="没有提供需要更新的字段",
            data=None
        )
    
    updated_role = await RoleService.update_role(role_id, update_dict)
    return ApiResponse.success(
        data=RoleResponse.model_validate(updated_role),
        msg="角色更新成功"
    )


@router.put("/{role_id}/whole", summary="全量更新角色信息")
async def update_role_whole(
    update_data: RoleWholeUpdate,
    role_id: int = Path(..., ge=1, description="角色ID")
):
    """
    全量更新角色信息
    
    Args:
        update_data: 完整的更新数据
        role_id: 角色ID
        
    Returns:
        包含更新后角色信息的响应
    """
    updated_role = await RoleService.update_role_whole(role_id, update_data.model_dump())
    return ApiResponse.success(
        data=RoleResponse.model_validate(updated_role),
        msg="角色更新成功"
    )


@router.delete("/{role_id}", summary="软删除角色")
async def delete_role(
    role_id: int = Path(..., ge=1, description="角色ID")
):
    """
    软删除角色(逻辑删除)
    
    Args:
        role_id: 角色ID
        
    Returns:
        删除操作的结果响应
    """
    await RoleService.delete_role(role_id)
    return ApiResponse.success(msg=f"角色ID {role_id} 已成功删除")


@router.delete("/{role_id}/true", summary="硬删除角色")
async def hard_delete_role(
    role_id: int = Path(..., ge=1, description="角色ID")
):
    """
    硬删除角色(物理删除)
    
    Args:
        role_id: 角色ID
        
    Returns:
        删除操作的结果响应
    """
    await RoleService.hard_delete_role(role_id)
    return ApiResponse.success(msg=f"角色ID {role_id} 已被永久删除")


@router.get("/{role_id}/permissions", summary="获取角色权限")
async def get_role_permissions(
    role_id: int = Path(..., ge=1, description="角色ID")
):
    """
    获取角色拥有的所有权限
    
    Args:
        role_id: 角色ID
        
    Returns:
        包含角色权限列表的响应
    """
    permissions = await RoleService.get_role_permissions(role_id)
    role = await RoleService.get_role_by_id(role_id)
    
    # 构造响应数据
    role_data = RoleWithPermissionsResponse(
        **role.__dict__,
        permissions=[permission.id for permission in permissions]
    )
    
    return ApiResponse.success(data=role_data)


@router.post("/{role_id}/permissions/{permission_id}", summary="为角色分配权限")
async def assign_permission_to_role(
    role_id: int = Path(..., ge=1, description="角色ID"),
    permission_id: int = Path(..., ge=1, description="权限ID")
):
    """
    为角色分配一个权限
    
    Args:
        role_id: 角色ID
        permission_id: 权限ID
        
    Returns:
        操作结果响应
    """
    success = await RoleService.assign_permission_to_role(role_id, permission_id)
    
    if success:
        return ApiResponse.success(msg="权限分配成功")
    else:
        return ApiResponse.success(msg="权限已存在，无需重复分配")


@router.delete("/{role_id}/permissions/{permission_id}", summary="移除角色权限")
async def remove_permission_from_role(
    role_id: int = Path(..., ge=1, description="角色ID"),
    permission_id: int = Path(..., ge=1, description="权限ID")
):
    """
    从角色中移除一个权限
    
    Args:
        role_id: 角色ID
        permission_id: 权限ID
        
    Returns:
        操作结果响应
    """
    success = await RoleService.remove_permission_from_role(role_id, permission_id)
    
    if success:
        return ApiResponse.success(msg="权限移除成功")
    else:
        return ApiResponse.success(msg="权限不存在，无需移除")


@router.put("/{role_id}/permissions", summary="更新角色权限")
async def update_role_permissions(
    role_id: int = Path(..., ge=1, description="角色ID"),
    permission_ids: List[int] = []
):
    """
    更新角色的权限列表(全量更新)
    
    Args:
        role_id: 角色ID
        permission_ids: 权限ID列表
        
    Returns:
        更新结果响应
    """
    assigned_count = await RoleService.update_role_permissions(role_id, permission_ids)
    return ApiResponse.success(
        msg=f"权限更新成功，共分配{assigned_count}个权限",
        data={"assigned_count": assigned_count}
    )


@router.get("/{role_id}/users", summary="获取角色用户列表")
async def get_role_users(
    role_id: int = Path(..., ge=1, description="角色ID")
):
    """
    获取拥有指定角色的所有用户
    
    Args:
        role_id: 角色ID
        
    Returns:
        包含用户列表的响应
    """
    users = await RoleService.get_role_users(role_id)
    
    from apps.auth.schemas.user_schema import UserResponse
    user_responses = [UserResponse.model_validate(user) for user in users]
    
    return ApiResponse.success(
        msg=f"成功获取角色用户列表",
        data=user_responses
    )


@router.post("/{role_id}/users/{user_id}", summary="为用户分配角色")
async def assign_role_to_user(
    role_id: int = Path(..., ge=1, description="角色ID"),
    user_id: int = Path(..., ge=1, description="用户ID")
):
    """
    为指定用户分配角色
    
    Args:
        role_id: 角色ID
        user_id: 用户ID
        
    Returns:
        操作结果响应
    """
    success = await RoleService.assign_role_to_user(role_id, user_id)
    return ApiResponse.success(
        msg=f"角色分配成功"
    )


@router.delete("/{role_id}/users/{user_id}", summary="从用户移除角色")
async def remove_role_from_user(
    role_id: int = Path(..., ge=1, description="角色ID"),
    user_id: int = Path(..., ge=1, description="用户ID")
):
    """
    从指定用户移除角色
    
    Args:
        role_id: 角色ID
        user_id: 用户ID
        
    Returns:
        操作结果响应
    """
    success = await RoleService.remove_role_from_user(role_id, user_id)
    return ApiResponse.success(
        msg=f"角色已从用户中移除"
    )


@router.put("/{role_id}/users", summary="更新角色用户")
async def update_role_users(
    role_id: int = Path(..., ge=1, description="角色ID"),
    user_ids: List[int] = []
):
    """
    更新角色的用户列表(全量更新)
    
    Args:
        role_id: 角色ID
        user_ids: 用户ID列表
        
    Returns:
        更新结果响应
    """
    assigned_count = await RoleService.update_role_users(role_id, user_ids)
    return ApiResponse.success(
        msg=f"用户更新成功，共分配{assigned_count}个用户",
        data={"assigned_count": assigned_count}
    )
